package com.leetcode.partition1;

import java.util.Arrays;

/**
 * @author `RKC`
 * @date 2021/9/24 14:32
 */
public class LC10正则表达式匹配 {

    public static boolean isMatch(String s, String p) {
        return dynamicProgramming(s, p);
    }

    public static void main(String[] args) {
        String s = "aaabb", p = "a*b*";
        System.out.println(isMatch(s, p));
    }

    private static boolean dynamicProgramming(String s, String p) {
        //模拟地址：https://alchemist-al.com/algorithms/regular-expression-matching
        //dp[i][j]：s的前i个字符和p的前j个字符是否能够匹配
        boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
        dp[0][0] = true;
        for (int i = 0; i < dp.length; i++) {
            for (int j = 1; j < dp[0].length; j++) {
                if (p.charAt(j - 1) == '*') {
                    //p中*前面的在s字符中出现0次，s=m，p=mi*
                    dp[i][j] = dp[i][j - 2];
                    if (!dp[i][j] && matches(s, p, i, j - 1)) {
                        //p中*前面的字符在s中出现多次或者在s中只出现1次
                        dp[i][j] = dp[i - 1][j];
                    }
                    continue;
                }
                //没有特殊字符，直接匹配
                dp[i][j] = matches(s, p, i, j) && dp[i - 1][j - 1];
            }
        }
        Arrays.stream(dp).forEach(val -> System.out.println(Arrays.toString(val)));
        return dp[s.length()][p.length()];
    }

    private static boolean matches(String s, String p, int i, int j) {
        if (i == 0) return false;
        if (p.charAt(j - 1) == '.') return true;
        return s.charAt(i - 1) == p.charAt(j - 1);
    }
}
